export { };
// 条件类型的使用
//工具类型
type IsString<T> = T extends string ? true : false;

type T0 = IsString<number>; // false
type T1 = IsString<string>; // true
type T2 = IsString<'ab'>; // true
type T3 = IsString<string[]>; // false
type T4 = IsString<boolean>; // false
// any和never特殊
type T5 = IsString<any>; // boolean
type T6 = IsString<never>; // never


// 条件列中的使用
type TypeName<T> = T extends string ? 'string' :
                  T extends number ? 'number' : 
                  T extends boolean ? 'boolean' :
                  T extends undefined ? 'undefined' :
                  T extends Function ? 'function' :
                  'object';
                 
type T11 = TypeName<string>; // 'string'
type T12 = TypeName<string | ((x: number) => void)>; // 联合类型 =》'string' | 'function'
type T14 = TypeName<number | string[] | undefined>;// 联合类型=> 'number' | 'object' | 'undefined'




// "裸"类型参数进行分布式匹配
type Naked<T> = T extends boolean ? 'Y' : 'N';
type N1 = Naked<string>; // 'N'
type N2 = Naked<boolean>; // 'Y'

//非 "裸"类型参数匹配
type WrapperTuple<T> = [T] extends [number | string] ? 'Y' : 'N';
type WrapperArray<T> = T[] extends boolean[] ? 'Y' : 'N';
type WrapperPromise<T> = Promise<T> extends Promise<boolean> ? 'Y' : 'N';

type W1 = WrapperTuple<string | number>;// 'Y'
type W2 = WrapperArray<string | number>;// 'N'
type W3 = WrapperPromise<string | number>;// 'N'



type Exclude<T, U> = T extends U ? never : T; 

type T20 = Exclude<'a' | 'b' | 'c', 'a' | 'b'>;// 'c'
// ('a' extends 'a' | 'b' ? never : 'a') => 'never'
// ('b' extends 'a' | 'b' ? never : 'b') => 'never'
// ('c' extends 'a' | 'b' ? never : 'c') => 'c'
// 最终=》 never ｜ never ｜ ‘c’ => 'c'



// 获取对象类型的除了函数之外的key组成的联合类型
type NonFunctionpropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? never : K
}[keyof T];

type user = {
  namd: string,
  age: number,
  id: boolean,
  fn: Function
};

type Names = NonFunctionpropertyNames<user>;//  "namd" | "age" | "id"

type NonFunctionProperties<T> = Pick<T, NonFunctionpropertyNames<T>>;
type Properyies = NonFunctionProperties<user>;//{ namd: string; age: number;id: boolean;}



// 类型的本质是一种数据的集合
interface Vector1D {
  x: number;
}

interface Vector2D {
  x: number,
  y: string
}

type SubtypeOf<T, U> = T extends U ? true : false;
type A = SubtypeOf<Vector2D, Vector1D>;// true



// 函数重载签名 的几种写法

// 第一种 普通函数的重载
// 重载签名
function greet(person: string): string;
function greet(person: string[]): string[];
// 实现签名
function greet(x: unknown): unknown {
  if (typeof x === 'string') {
    return x;
  } else if (Array.isArray(x)) {
    return x;
  };
  throw new Error('never');
}

// 第二种 类方法的重载

class Calculator {
  // 方法重载签名
  add(x: number, b: number): number;
  add(x: string, b: string): string;
  add(x: string, b: number): string;
  add(x: number, b: string): string;
  // 实现签名
  add(x: number | string, y: number | string) {
    if (typeof x === 'string' || typeof y === 'string') {
      return (<string>x).toString() + (y as string).toString();
    }
    return x + y
  }
}